package hk.com.fgoproduction.getdroplets.Lib.IO

class SpeedLimiter(val maxSpeed: Int, val fixedTimeInterval: Int, val packetSize: Int) {
    var count: Int = 0
    var timeLog: Long = 0L
    var timeDelayed: Long = 0L

    interface ISpeedLimiter {
        fun stopTheWorld()
    }

    //target: max rate(Rm)/rate(R) = 1 => Rm = R
    //Rm is const
    //R = packet (const p) * count (c) / time (t)
    //if in interval time (to), R >= Rm
    //t need to increase to decrease the R
    //=> R = pc/(t+dt) = Rm
    //=> pc/Rm-t = dt

    private fun main(cb: ISpeedLimiter) {
        val timeDiff = System.currentTimeMillis() - timeLog
        if (timeLog != 0L && timeDiff <= fixedTimeInterval) {
            val rate = packetSize * count / timeDiff
            if (rate >= maxSpeed) {
                timeDelayed = (packetSize * count) / maxSpeed - timeDiff
                cb.stopTheWorld()
                count = 0
                timeLog = System.currentTimeMillis()
            }
        } else {
            timeLog = System.currentTimeMillis()
        }
    }

    fun start() {
        timeLog = System.currentTimeMillis()
    }

    fun update(cb: ISpeedLimiter) {
        count++
        main(cb)
    }

}